import { Component, Vue } from 'vue-property-decorator';
import { IResponse } from '@/interfaces/common.interface';
import style from '@/styles/views/cateye.module.less';
import { EapLayout, EapLock, EapDoor } from '@/components';
import {
  Button,
  Cell,
  CellGroup,
  Circle,
  Dialog,
  Field,
  Icon,
  Loading,
  NavBar,
  Overlay,
  Radio,
  RadioGroup,
  SwipeCell
} from 'vant';
import cameraOnSvg from '@/assets/svg/cateye-scene/camera-on.svg';
import cameraOffSvg from '@/assets/svg/cateye-scene/camera-off.svg';
import lwirOnSvg from '@/assets/svg/lwir/lwir.svg';
import lwirOffOnSvg from '@/assets/svg/lwir/lwir-disabled.svg';
import lightOnSvg from '@/assets/svg/light/light.svg';
import lightOffOnSvg from '@/assets/svg/light/light-disabled.svg';
import { IDevice, IDeviceListResp } from '@/interfaces/api.interface';
import _ from 'lodash';
import Utils from '@/common/Utils';

Vue.use(Dialog);

function getDeviceType(dev: IDevice) {
  const {
    report: { type, model, vendor, name }
  } = dev;
  if (type === 'device.lock' && model === 'IDLOCK01B') {
    return 'lock';
  } else if (type === 'device.hwjj' && model === 'IDHWJJ01B') {
    return 'lwir';
  } else if (model === 'aqcn02' && name === 'light' && vendor === 'lumi') {
    return 'light';
  } else if (type === 'camera') {
    return 'camera';
  }
}

interface ISyncData {
  cameraId: string;
  lockId: string;
  lwirId: string;
  lightId: string;
}

@Component({
  components: {
    'eap-layout': EapLayout,
    'van-nav-bar': NavBar,
    'eap-lock': EapLock,
    'eap-door': EapDoor,
    'van-radio-group': RadioGroup,
    'van-radio': Radio,
    'van-cell-group': CellGroup,
    'van-cell': Cell,
    'van-swipe-cell': SwipeCell,
    'van-button': Button,
    'van-icon': Icon,
    'van-field': Field,
    'van-overlay': Overlay,
    'van-circle': Circle,
    'van-loading': Loading
  },
  sockets: {
    connect() {
      // 说明是断线重连
      this.$socket.client.emit('sync', (data: ISyncData) => {
        (this.$data.cameraId = data.cameraId),
          (this.$data.lockId = data.lockId),
          (this.$data.lwirId = data.lwirId),
          (this.$data.lightId = data.lightId);
      });
    },
    members(data) {
      this.$data.members = data;
    },
    devices(data) {
      this.$data.list = data;
    },
    join(dev) {
      const type = getDeviceType(dev);
      if (type === 'camera') {
        this.$data.cameraId = dev.devid;
      } else if (type === 'lock') {
        this.$data.lockId = dev.devid;
      } else if (type === 'lwir') {
        this.$data.lwirId = dev.devid;
      } else if (type === 'light') {
        this.$data.lightId = dev.devid;
      }
    },
    lost(dev) {
      const type = getDeviceType(dev);
      if (type === 'camera') {
        this.$data.cameraId = '';
        this.$edger.notify.error('摄像头设备丢失！');
      } else if (type === 'lock') {
        this.$data.lockId = '';
        this.$edger.notify.error('门锁设备丢失！');
      } else if (type === 'lwir') {
        this.$data.lwirId = '';
        this.$edger.notify.error('红外感应设备丢失！');
      } else if (type === 'light') {
        this.$data.lightId = '';
        this.$edger.notify.error('小米灯泡设备丢失！');
      }
    },
    error(msg) {
      this.$edger.notify.error(msg);
    },
    success(msg) {
      this.$edger.notify.success(msg);
    },
    people() {
      this.$edger.notify.info('检测到有人出现！');
    },
    lock(data) {
      this.$data.open = data === 'ON';
    },
    image(data) {
      this.$data.base64Str = data;
    },
    similarity(data) {
      this.$data.similarity = data;
    },
    emotion(data) {
      if (data === 'happy') {
        this.$data.emotion = 'happy';
      } else if (data === 'sad') {
        this.$data.emotion = 'sad';
      } else {
        this.$data.emotion = 'normal';
      }
    },
    face(data) {
      this.$data.faceInfo = data;
    }
  }
})
export default class Cateye extends Vue {
  private cameraId = '';
  private lockId = '';
  private lwirId = '';
  private lightId = '';
  private open = false;
  private model = {
    show: false,
    type: 'camera',
    title: '摄像头'
  };
  private list: IDevice[] = [];
  private members: string[] = [];
  private base64Str = '';
  private faceInfo = { name: '-' };
  private isMemberModel = false;
  private uploadPreviewSrc = '';
  private memberInfo: any = {
    name: '',
    file: null
  };
  private submitLoading = false;
  private similarity = 0;
  private emotion: 'happy' | 'sad' | 'normal' = 'normal';
  private devLineAngle = 0;

  private get alarmText() {
    if (!this.lockId && !this.cameraId && !this.lwirId) {
      return '请选择关联设备';
    } else if (!this.lockId && this.cameraId && this.lwirId) {
      return '请选择门锁设备';
    } else if (!this.cameraId && this.lockId && this.lwirId) {
      return '请选择摄像头设备';
    } else if (!this.lwirId && this.lockId && this.cameraId) {
      return '请选择红外感应设备';
    } else if (!this.lightId && this.lockId && this.cameraId && this.lwirId) {
      return '请选择小米灯泡设备';
    } else {
      return '';
    }
  }

  private get emotionImage() {
    if (this.emotion === 'happy') {
      return require('../assets/emotion/happy.svg');
    } else if (this.emotion === 'sad') {
      return require('../assets/emotion/sad.svg');
    } else {
      return require('../assets/emotion/normal.svg');
    }
  }

  private get progressColor() {
    if (this.similarity >= 60) {
      return '#07c160';
    } else if (this.similarity >= 50 && this.similarity < 60) {
      return '#ff976a';
    } else {
      return '#ee0a24';
    }
  }

  public created() {
    this.listenPermission();
    this.$socket.client.emit('init');
  }

  public mounted() {
    // 设备连接线旋转角度计算
    this.calcDevLineAngle();
    window.onresize = () => {
      this.calcDevLineAngle();
    };
  }

  /* 监听权限变化 */
  private listenPermission() {
    this.$edger.onAction('permission', data => {
      console.log('[permission change]:', data);
      this.$socket.client.emit('init-scene');
    });
  }

  public render() {
    return (
      <eap-layout>
        <van-nav-bar title='猫眼' slot='header' class={style['nav-bar-shadow']} />
        <div class={style['cateye']}>
          <div class={style['cateye-container']}>
            {this.renderViewport()}
            {this.renderDev()}
            <div class={style['cateye-lock']}>
              <eap-lock value={this.open} disabled={!this.lockId} on-change={this.switchLock}></eap-lock>
            </div>
            {this.renderMember()}
          </div>
        </div>
        {this.renderDevModel()}
        {this.renderMemberModel()}
        {this.renderLoading()}
      </eap-layout>
    );
  }

  private renderViewport() {
    return (
      <div class={style['cateye-viewport']}>
        <div class={style['cateye-viewport-image']}>
          {this.base64Str && <img src={'data:image/png;base64,' + this.base64Str} />}
        </div>
        <div class={style['cateye-viewport-info']}>
          <div class={style['cateye-viewport-info-left']}>
            <h4>扫描数据：</h4>
            <div>
              <p>
                <span>姓名：</span>
                <span>{this.faceInfo.name}</span>
              </p>
              <p>
                <span>犯罪记录：</span>
                <span>无</span>
              </p>
            </div>
          </div>
          <div class={style['cateye-viewport-info-right']}>
            <van-circle
              value={this.similarity}
              size={55}
              speed={100}
              text={this.similarity + '%'}
              stroke-width={110}
              color={this.progressColor}
              layer-color='#ddd'
            />
            <img src={this.emotionImage} class={style['cateye-viewport-info-emotion']} />
          </div>
        </div>
      </div>
    );
  }

  private renderDev() {
    return (
      <div class={style['cateye-dev']}>
        <div class={style['cateye-dev-container']}>
          <img
            src={this.cameraId ? cameraOnSvg : cameraOffSvg}
            alt='camera'
            on-click={() => this.showModel('camera')}
          />
          <img src={this.lwirId ? lwirOnSvg : lwirOffOnSvg} alt='lwir' on-click={() => this.showModel('lwir')} />
        </div>

        <div ref='cateye-dev-line' class={style['cateye-dev-line']}>
          <i
            class={this.cameraId && style['cateye-dev-line-active']}
            style={{ transform: `translateY(12px) rotateZ(${this.devLineAngle}deg)` }}></i>
          <i
            class={[style['cateye-dev-line-lwir'], this.lwirId && style['cateye-dev-line-active']]}
            style={{ transform: `translateY(-12px) rotateZ(-${this.devLineAngle}deg)` }}></i>
        </div>

        <img src={require('@/assets/svg/cateye-scene/edgeros-net.svg')} alt='camera' />

        <div class={style['cateye-dev-line']}>
          <i
            class={this.lockId && style['cateye-dev-line-active']}
            style={{ transform: `translateY(12px) rotateZ(-${this.devLineAngle}deg)` }}></i>
          <i
            class={[style['cateye-dev-line-light'], this.lightId && style['cateye-dev-line-active']]}
            style={{ transform: `translateY(-12px) rotateZ(${this.devLineAngle}deg)` }}></i>
        </div>

        <div class={style['cateye-dev-container']}>
          <eap-door
            v-model={this.open}
            color={this.lockId ? '#1afa29' : '#cdcdcd'}
            on-click={() => this.showModel('lock')}></eap-door>
          <img
            src={this.lightId ? lightOnSvg : lightOffOnSvg}
            alt='light'
            on-click={() => this.showModel('light')}
            style={{ width: '35px', marginTop: '25px' }}
          />
        </div>

        <span>{this.alarmText}</span>
      </div>
    );
  }

  private renderDevModel() {
    return (
      <van-dialog
        v-model={this.model.show}
        title={this.model.title}
        showConfirmButton={false}
        closeOnClickOverlay
        class={style['model']}>
        <div class={style['model-list']}>{this.renderSelectDevList()}</div>
      </van-dialog>
    );
  }

  private renderMemberModel() {
    return (
      <van-dialog
        v-model={this.isMemberModel}
        title='添加授权成员'
        show-cancel-button
        on={{ confirm: this.submitAddMember }}>
        <van-field v-model={this.memberInfo.name} label='姓名' placeholder='请输入成员姓名/备注' />
        <van-field center clearable label='照片'>
          <div slot='input' class={style['model-input']}>
            <input
              type='file'
              id='video-input'
              accept='image/*'
              capture='user'
              on-input={this.inputHandle}
              on-change={this.inputHandle}
            />
            {this.uploadPreviewSrc && <img src={this.uploadPreviewSrc} alt='photo' />}
          </div>
        </van-field>
      </van-dialog>
    );
  }

  private renderSelectDevList() {
    return (
      <van-radio-group
        value={
          this.model.type === 'camera'
            ? this.cameraId
            : this.model.type === 'lock'
            ? this.lockId
            : this.model.type === 'lwir'
            ? this.lwirId
            : this.lightId
        }>
        <van-cell-group>
          {this.list.map((item: IDevice) => {
            return (
              <van-cell
                title={item.alias}
                clickable
                on-click={() => {
                  this.selectDevice(item);
                }}>
                <van-radio name={item.devid} slot='right-icon' />
              </van-cell>
            );
          })}
        </van-cell-group>
      </van-radio-group>
    );
  }

  private renderMember() {
    return (
      <div class={style['cateye-authorize-numbers']}>
        <h4>
          授权成员信息
          <van-button type='primary' icon='plus' text='添加' size='mini' on-click={this.showMemberModel} />
        </h4>
        {this.members.map((name: string) => {
          return (
            <van-swipe-cell>
              <van-cell title={name}>
                <van-button square type='danger' text='删除' size='mini' on-click={() => this.deleteMember(name)} />
              </van-cell>
            </van-swipe-cell>
          );
        })}
      </div>
    );
  }

  private renderLoading() {
    return (
      <van-overlay
        show={this.submitLoading}
        style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
        <van-loading color='#0094ff' vertical>
          正在给角色授权中...
        </van-loading>
      </van-overlay>
    );
  }

  // 显示设备模态框
  private showModel(type: 'camera' | 'lock' | 'lwir' | 'light') {
    this.model = {
      type,
      show: true,
      title:
        type === 'camera'
          ? '选择摄像头'
          : type === 'lock'
          ? '选择门锁'
          : type === 'lwir'
          ? '选择红外感应'
          : '选择米家灯泡'
    };
  }

  // 显示添加成员模态框
  private showMemberModel() {
    this.uploadPreviewSrc = '';
    this.memberInfo = {
      name: '',
      file: null
    };
    this.isMemberModel = true;
  }

  // 删除授权成员
  private async deleteMember(name: string) {
    this.$socket.client.emit('delete-member', name);
  }

  // 选择场景设备
  private async selectDevice(dev: IDevice) {
    let delete_id = '';
    const type = getDeviceType(dev);
    if (this.model.type === 'camera') {
      if (this.cameraId === dev.devid) {
        return;
      }
      if (type !== 'camera') {
        return this.$edger.notify.error('请选择摄像头设备！');
      }
      delete_id = this.cameraId;
    } else if (this.model.type === 'lock') {
      if (this.lockId === dev.devid) {
        return;
      }
      if (type !== 'lock') {
        return this.$edger.notify.error('请选择门锁设备！');
      }
      delete_id = this.lockId;
    } else if (this.model.type === 'lwir') {
      if (this.lwirId === dev.devid) {
        return;
      }
      if (type !== 'lwir') {
        return this.$edger.notify.error('请选择红外感应设备！');
      }
      delete_id = this.lwirId;
    } else if (this.model.type === 'light') {
      if (this.lightId === dev.devid) {
        return;
      }
      if (type !== 'light') {
        return this.$edger.notify.error('请选择小米灯泡设备！');
      }
      delete_id = this.lightId;
    }
    this.$socket.client.emit('change-scene-devices', { add_id: dev.devid, delete_id });
    this.model.show = false;
  }

  // 开锁
  private async switchLock(state: boolean) {
    if (state) {
      // 可开不可关
      this.$socket.client.emit('send-device-message', {
        devid: this.lockId,
        data: { method: 'set', unlock: 'ON', open_time: 5000 }
      });
    }
  }

  // 文件上传处理
  private inputHandle(e: Event) {
    const file = (e.target as HTMLInputElement).files![0];
    this.memberInfo.file = file;
    Utils.filetoDataURL(file, (url: string) => {
      this.uploadPreviewSrc = url;
    });
  }

  // 新增授权成员
  private async submitAddMember() {
    if (!this.memberInfo.name || !this.memberInfo.file) {
      return this.$edger.notify.error('上传信息不全！');
    }
    this.submitLoading = true;
    const formData = new FormData();
    formData.append('name', this.memberInfo.name);
    formData.append('file', this.memberInfo.file!);
    try {
      const res: IResponse = await this.$api.uploadFile(formData);
      if (!res.result) {
        this.$edger.notify.error(res.message);
      }
    } catch (error) {
      this.$edger.notify.error('操作出现未知错误，请退出重试！');
    } finally {
      this.submitLoading = false;
    }
  }

  /**
   * 计算设备连接线的角度
   * @returns 返回角度
   */
  public calcDevLineAngle() {
    const devLineDom = this.$refs['cateye-dev-line'] as HTMLDivElement;
    if (!devLineDom) {
      return this.$edger.notify.error('页面初始化失败，请退出重试！');
    } else {
      const w = devLineDom.clientWidth;
      const h = devLineDom.clientHeight;
      if (!w || !h) {
        return this.$edger.notify.error('页面初始化失败，请退出重试！');
      } else {
        // 计算角度
        const radina = Math.atan2(h / 2, w);
        this.devLineAngle = Math.floor(180 / (Math.PI / radina));
      }
    }
  }
}
